package it.unipg.bipod.web;

import it.unipg.bipod.applicationLogic.*;
import it.unipg.bipod.dataModel.*;

import java.text.*;

import java.util.Arrays;
import java.util.Comparator;

/**
 * DocenteRichiesteBean gestisce le attività del docente collegate alle richieste di assegnamento
 * da lui effettuate.<br>
 * Permette di consultare l'elenco delle richieste effettuate e di cancellare le richieste
 * appartenenti a bandi ancora attivi.<br>
 * E' presente una sottoclasse pubblica: RichiestaBean.<br>
 * Eventuali messaggi o errori vengono segnalati mediante i metodi forniti da DefaultBean.
 * 
 * @author Lorenzo Porzi
 * @see DocenteBean
 * @see DefaultBean
 */
public class DocenteRichiesteBean extends DefaultBean {
	private DocenteApplication application;
	
	/**
	 * Costruisce un DocenteRichiesteBean associato alla DocenteApplication fornita.
	 * 
	 * @param application la DocenteApplication da associare a questo DocenteRichiesteBean.
	 */
	public DocenteRichiesteBean(DocenteApplication application) {
		super();
		
		this.application = application;
	}
	
	/* --------------------------------
	 * Metodi per l'estrazione dei dati
	 * -------------------------------- */
	
	/**
	 * Recupera l'elenco delle richieste effettuate.
	 * 
	 * @return un array di RichiestaBean con le richieste recuperate.
	 */
	public RichiestaBean[] getRichieste() {
		try {
			// Recupera le richieste
			Richiesta[] richieste = application.getRichiesteEffettuate();
			
			// Le ordina per data
			Arrays.sort(richieste, new Comparator<Richiesta>() {
				public int compare(Richiesta r1, Richiesta r2) {
					return r2.getDataRichiesta().compareTo(r1.getDataRichiesta());
				}
			});
			
			// Recupera i bandi
			Bando[] bandi = application.getBandi();
			int[] idBandiAttivi = new int[bandi.length];
			for (int i = 0; i < bandi.length; ++i)
				idBandiAttivi[i] = bandi[i].getIdBando();
			
			// Riempe il risultato
			RichiestaBean[] richiesteBean = new RichiestaBean[richieste.length];
			for (int i = 0; i < richieste.length; ++i)
				richiesteBean[i] = new RichiestaBean(richieste[i], idBandiAttivi);
			
			return richiesteBean;
		} catch (ApplicationException e) {
			RichiestaBean[] vuoto = {};
			return vuoto;
		}
	}
	
	/**
	 * Restituisce il numero di richieste effettuate.
	 * 
	 * @return il numero di richieste effettuate.
	 */
	public int getNumeroRichieste() {
		try {
			// Recupera le richieste
			return application.getRichiesteEffettuate().length;
		} catch (ApplicationException e) {
			return 0;
		}
	}
	
	/* -----------
	 * Sottoclassi
	 * ----------- */

	/**
	 * BandoBean incapsula una richiesta fornendo alcune funzionalita' aggiuntive.<br>
	 * Permette di cancellare la richiesta incapsulata, di accedere alle sue proprieta',
	 * nonche' di accedere alle proprieta' dell'insegnamento associato.
	 * 
	 * @author Lorenzo Porzi
	 *
	 */
	public class RichiestaBean {
		private Richiesta richiesta; // La richiesta incapsulata
		private InsegnamentoCorso insegnamento; // L'insegnamento collegato alla richiesta
		private boolean attiva; // Lo stato di attività del bando a cui appartiene la richiesta
		
		/**
		 * Costruisce una RichiestaBean associata ad una Richiesta.
		 * 
		 * @param richiesta la Richiesta da associare a questa RichiestaBean
		 * @param idBandiAttivi l'elenco degli id dei bandi attivi, utilizzato per determinare
		 * se questa richiesta è associata ad un bando ancora attivo.
		 * @throws ApplicationException
		 */
		public RichiestaBean(Richiesta richiesta, int[] idBandiAttivi) throws ApplicationException {
			this.richiesta = richiesta;
			this.insegnamento = application.getInsegnamento(richiesta);
			
			// Controlla che la richiesta afferisca ad un bando attivo
			this.attiva = false;
			for (int idBando : idBandiAttivi)
				if (idBando == insegnamento.getBando())
					this.attiva = true;
		}
		
		/* ----------------------------------
		 * Setters e getters per le proprietà
		 * ---------------------------------- */
		
		public InsegnamentoCorso getInsegnamento() {
			return insegnamento;
		}
		
		public Richiesta getRichiesta() {
			return richiesta;
		}
		
		public String getDataPubblicazioneBando() {
			Format dateFormat = new SimpleDateFormat("dd/MM/yyyy");
			
			return dateFormat.format(insegnamento.getDataPubblicazioneBando());
		}
		
		public String getDataRichiesta() {
			Format dateFormat = new SimpleDateFormat("dd/MM/yyyy");
			Format timeFormat = new SimpleDateFormat("HH.mm");
			
			String data = dateFormat.format(richiesta.getDataRichiesta());
			data += " alle ";
			data += timeFormat.format(richiesta.getDataRichiesta());
			
			return data;
		}
		
		/**
		 * @return {@code true} se il bando a cui appartiene l'insegnamento associato a questa richiesta
		 * e' attivo, altrimenti {@code false}.
		 */
		public boolean getAttiva() {
			return attiva;
		}
		
		/* ---------------------
		 * Metodi di navigazione
		 * --------------------- */
		
		/**
		 * Cancella questa richiesta di assegnamento.<br>
		 * Questo metodo utilizza le seguenti proprieta' di presentation.ini:
		 * <ul>
		 *   <li><b>msgCancellaRichiestaRiuscita</b>: il messaggio visualizzato quando la cancellazione riesce.</li>
		 *   <li><b>msgErroreCancellaRichiesta</b>: il messaggio visualizzato quando la cancellazione fallisce.</li>
		 * </ul>
		 */
		public void cancellaRichiesta() {
			try {
				application.cancellaRichiesta(getInsegnamento().getInsegnamento());
				
				addInfoMessage(getSettings().getProperty("msgCancellaRichiestaRiuscita"));
			} catch (ApplicationException e) {
				addWarnMessage(getSettings().getProperty("msgErroreCancellaRichiesta"));
			}
		}
	}
}
